package tcm.com.gistone.controller;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import tcm.com.gistone.database.config.GetBySqlMapper;
import tcm.com.gistone.database.entity.*;
import tcm.com.gistone.database.mapper.*;
import tcm.com.gistone.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author:renqiang
 * @Param:
 * @Description:主题词管理
 * @Date:14:50 2017/7/18
 */
@RestController
@RequestMapping( "word" )
@Transactional
public class WordController {
    private final static org.slf4j.Logger logger = LoggerFactory.getLogger(ClientUtil.class);
    @Autowired
    private BookinfoMapper bm;
    @Autowired
    private SectionMapper sm;
    @Autowired
    private WordMapper wm;
    @Autowired
    private WsRelationMapper wsm;
    @Autowired
    private WordRelationMapper wrm;
    @Autowired
    private SpecialMapper spm;
    @Autowired
    private ThemeMapper tm;
    @Autowired
    private ConfidenceMapper cm;
    @Autowired
    private WordsRelationMapper wordsRelationMapper;
    @Autowired
    GetBySqlMapper gm;
    @Autowired
    private ModifyWord modifyWord;
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

    @Autowired
    private ConfigUtil configUtil;

    /*查询所有主题词类型*/
    @RequestMapping( value = "getThemes" )
    public EdatResult getTheme(HttpServletRequest request, HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            long specialId = data.getLong("specialId");
            if (specialId == 0) {
                List<Theme> themes = tm.selectAll();
                return EdatResult.build(0, "success", themes);
            } else {
                List<Theme> themes = tm.selectThemeBySpecial(specialId);
                return EdatResult.build(0, "success", themes);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "查询失败");
        }
    }

    /*添加主题词*/
    @ResponseBody
    @RequestMapping( value = "recordWord", method = RequestMethod.POST )
    @Transactional( rollbackFor = Exception.class )
    public EdatResult recordWord(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            List<Bookinfo> list = bm.selectAvai();
            if (list.size() > 0) {
                return EdatResult.build(1, "存在正在构建的文献，重新构建失败");
            }
            String word = data.getString("word");
            if (null == word || word == "") {
                return EdatResult.build(1, "录入失败，主题词为空");
            }
            String alias = data.getString("alias");/*别名*/
            long specialId = data.getLong("specialId");
            long wordType = data.getLong("type");
            Word w = wm.selectByWord(specialId, word, wordType);
            if (w != null) {
                return EdatResult.build(1, "录入失败，主题词重复");
            } else {
                Word nw = new Word();
                nw.setThemeType(wordType);
                nw.setSpecialId(specialId);
                nw.setWord(word);
                wm.insert(nw);
                Word w1 = wm.selectByWord(specialId, word, wordType);
                w1.setParentId(w1.getWordId());
                wm.updateByPrimaryKey(w1);
                long wordId = w1.getWordId();
                /*添加别名*/
                if (null != alias && !alias.equals("")) {
                    String[] arr = alias.split(",|，");
                    Set<String> strings = new HashSet<>();
                    /*判断是否存在与主题词或别名重复的别名*/
                    for (int i = 0; i < arr.length; i++) {
                        String tem = arr[i].trim();
                        if (!tem.equals("")) {
                            if(strings.contains(tem)){
                                return EdatResult.build(1, "存在与主题词或别名重复的别名:"+tem);
                            }
                            strings.add(tem);
                        }
                    }
                    for (int i = 0; i < arr.length; i++) {
                        String tem = arr[i].trim();
                        if (!tem.equals("")) {
                            Word word1 = new Word();
                            word1.setParentId(wordId);
                            word1.setWord(tem);
                            word1.setSpecialId(specialId);
                            word1.setThemeType(wordType);
                            wm.insert(word1);
                        }
                    }
                }
                /*添加新主题词的知识构建数据*/
                modifyWord.addWsRelationByWord(wordId);
                return EdatResult.build(0, "录入成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("{\"status\":\"1\",\"msg\":\"录入失败\",\"data\":\"\"}");
            throw e;
        }
    }

    /*删除主题词*/
    @RequestMapping( value = "deleteWord", method = RequestMethod.POST )
    @Transactional( rollbackFor = Exception.class )
    public EdatResult deleteWord(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            List<Bookinfo> list = bm.selectAvai();
            if (list.size() > 0) {
                return EdatResult.build(1, "存在正在构建的文献，重新构建失败");
            }
            JSONArray array = data.getJSONArray("wordIds");
            for (int i = 0; i < array.size(); i++) {
                long wordId = array.getLong(i);
                if (i == 0) {
                    Word word = wm.selectByPrimaryKey(wordId);
                    Special special = spm.selectByPrimaryKey(word.getSpecialId());
                    if (special.getStatus() != 1) {
                        special.setStatus(1);
                        spm.updateByPrimaryKey(special);
                    }
                }
                /*删除该主题词的知识库*/
                deleteRelationByWord(wordId);
                String sql = "delete from tb_word where parent_id = " + wordId;
                gm.delete(sql);
            }
            return EdatResult.build(0, "删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("{\"status\":\"1\",\"msg\":\"删除失败\",\"data\":\"\"}");
            throw e;
        }
    }

    /*删除某词的关联关系*/
    public void deleteRelationByWord(long wordId) {
        /*删除分组信息*/
        String sql4 = "delete from tb_group_word where  word_id = " + wordId;
        gm.delete(sql4);
        String sql1 = "delete from tb_ws_relation where word_id = " + wordId;
        gm.delete(sql1);
        String sql3 = "delete from tb_words_relation where word_id = " + wordId + " or ano_word_id = " + wordId;
        gm.delete(sql3);
        String sql11 = "delete from tb_ws_relation_copy where word_id = " + wordId;
        gm.delete(sql11);
        String sql33 = "delete from tb_words_relation_copy where word_id = " + wordId + " or ano_word_id = " + wordId;
        gm.delete(sql33);
    }

    /*修改主题词*/
    @RequestMapping( value = "updateWord", method = RequestMethod.POST )
    @Transactional( rollbackFor = Exception.class )
    public EdatResult updateWord(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            List<Bookinfo> list = bm.selectAvai();
            /*构建过程无法修改主题词*/
            if (list.size() > 0) {
                return EdatResult.build(1, "存在正在构建的文献，重新构建失败");
            }
            long wordId = data.getLong("id");
            long specialId = data.getLong("specialId");
            Word parentWord = wm.selectByPrimaryKey(wordId);
            String word = data.getString("word").trim();
            String alias = data.getString("alias").trim();/*别名*/
            String[] arry = alias.split(",|，");
            long wordType = data.getLong("type");
            if (!parentWord.getWord().equals(word) || parentWord.getThemeType() != wordType) {
                Word word1 = wm.selectByWord(specialId, word, wordType);
                if (null != word1) {
                    return EdatResult.build(1, "修改失败，主题词重复");
                }
            }
            /*删除之前的知识构建数据*/
            deleteRelationByWord(wordId);
            parentWord.setSpecialId(specialId);
            parentWord.setThemeType(wordType);
            parentWord.setWord(word);
            wm.updateByPrimaryKey(parentWord);
            /*删除旧别名*/
            String sql = "delete from tb_word where parent_id = " + wordId + " and word_id != " + wordId;
            gm.delete(sql);
            Set<String> strings = new HashSet<>();
            for (int i = 0; i < arry.length; i++) {
                String tem = arry[i].trim();
                if (!tem.equals("")) {
                    /*别名与主题词或与别名重复*/
                    if(strings.contains(tem)){
                        return EdatResult.build(1, "存在与主题词或别名重复的别名:"+tem);
                    }
                    strings.add(tem);
                }
            }
            for (int i = 0; i < arry.length; i++) {
                if (!arry[i].trim().equals("")) {
                    Word word1 = new Word();
                    word1.setSpecialId(specialId);
                    word1.setParentId(parentWord.getWordId());
                    word1.setWord(arry[i].trim());
                    word1.setThemeType(wordType);
                    wm.insert(word1);
                }
            }
            /*添加新的知识构建数据*/
            modifyWord.addWsRelationByWord(wordId);
            return EdatResult.build(0, "更新成功");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("{\"status\":\"1\",\"msg\":\"更新失败\",\"data\":\"\"}");
            throw e;
        }
    }


    /*查询主题词*/
    @RequestMapping( value = "selectWord", method = RequestMethod.POST )
    public Map selectWord(HttpServletRequest request, HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            int pageNumber = Integer.parseInt(request.getParameter("pageNumber"));
            int pageSize = Integer.parseInt(request.getParameter("pageSize"));
            String keyWord = request.getParameter("keyWord");
            long specialId = Long.parseLong(request.getParameter("specialId"));
            String sql = "";
            String sql3 = "";
            String sql1 = "";
            if (!keyWord.equals("")) {
                sql3 = " and  word like '%" + keyWord + "%'";
            }
            if (specialId == 0) {
                sql = "select distinct parent_id as id from tb_word where 1=1 " + sql3 + " order by parent_id  limit " + pageNumber + "," + pageSize;
                sql1 = "select count(distinct parent_id) as total from tb_word where  1=1  " + sql3;
            } else {
                sql = "select distinct parent_id as id from tb_word where special_id = " + specialId + sql3 + " order by parent_id  limit " + pageNumber + "," + pageSize;
                sql1 = "select count(distinct parent_id) as total from tb_word where    special_id = " + specialId + sql3;
            }
            List<Map> result = gm.findRecords(sql);
            if (result.size() < 1 || result.get(0) == null) {
                return null;
            }
            for (int i = 0; i < result.size(); i++) {
                Map map = result.get(i);
                long id = (long) map.get("id");
                String sql2 = "select word from tb_word where  parent_id = " + id + " and word_id != " + id + " order by word_id ";
                Word word = wm.selectByPrimaryKey(id);
                if (word == null) {
                    continue;
                }
                List<Map> res = gm.findRecords(sql2);
                String str = "";/*别名*/
                for (int j = 0; j < res.size(); j++) {
                    if (j == 0) {
                        str += res.get(j).get("word");
                    } else {
                        str += "," + res.get(j).get("word");
                    }
                }
                map.put("word", word.getWord());
                map.put("alias", str);
                map.put("id", id);
                map.put("specialId", word.getSpecialId());
                map.put("type", word.getThemeType());
            }
            int total = gm.findrows(sql1);
            Map map = new HashMap();
            map.put("total", total);
            map.put("rows", result);
            map.put("page", pageNumber / pageSize);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /*查询含有主题词的专题*/
    @RequestMapping( value = "selectAvailableSpecial" )
    public EdatResult selectAvailableSpecial(HttpServletRequest request, HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            String sql = "select * from tb_special where special_id in (select distinct special_id from tb_word)";
            List<Map> list = gm.findRecords(sql);
            return EdatResult.ok(list);
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "查询失败");
        }
    }


    /*删除图片*/
    @RequestMapping( value = "deleteImg" )
    public EdatResult deleteImg(HttpServletRequest request, HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            long id = data.getLong("id");
            String sql = "update tb_word set pic_url = null where word_id = " + id;
            gm.update(sql);
            return EdatResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "删除失败");
        }
    }


    /*批量录入主题词*/
    @RequestMapping( value = "recordWords", method = RequestMethod.POST )
    @Transactional( rollbackFor = Exception.class )
    public EdatResult recordWords(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            long t1 = System.currentTimeMillis();
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            List<Bookinfo> list3 = bm.selectAvai();
            if (list3.size() > 0) {
                return EdatResult.build(1, "存在正在构建的文献，重新构建失败");
            }
            long specialId = data.getLong("specialId");
            Special special = spm.selectByPrimaryKey(specialId);
            String specialName = special.getSpecialName();
            FileUtil.clearInfoForFile(configUtil.getLogUrl());
            Date now = new Date();
            FileUtil.writeToTxt(configUtil.getLogUrl(), " 开始更新" + specialName + "专题主题词表");
            String url = configUtil.getUrl() + "Files/Words/" + special.getSpecialName();
            File file1 = new File(url);
            if (!file1.exists()) {
                file1.mkdir();
            }
            List<Theme> list = tm.selectThemeBySpecial(specialId);/*获取主题词类型*/
            int total = 0;
            List files = new ArrayList();
            for (Theme theme : list) {
                String name = theme.getThemeName();
                File file = new File(url + "/dataFiles/" + name + ".xls");
                if (!file.exists()) {
                    files.add(name);
                }
            }
            /*检查文件*/
            if (files.size() > 0) {
                return EdatResult.build(1, "缺少" + files.toString() + "文件");
            }
            /*删除主题词数据*/
            String sql = "delete from tb_word where special_id = " + specialId;
            String sql1 = "delete from tb_group_word  where word_id in  (select word_id FROM tb_word where  special_id = " + specialId + ")";

            String sql2 = "delete from tb_ws_relation  where book_id in  (select book_id FROM tb_special_book where  special_id = " + specialId + ")";
            String sql3 = "delete from tb_words_relation  where book_id in  (select book_id FROM tb_special_book where  special_id = " + specialId + ")";
            String sql4 = "delete from tb_confidence" + specialId + "  where word_id in  (select word_id FROM tb_word where  special_id = " + specialId + ")";
            gm.delete(sql1);
            FileUtil.writeToTxt(configUtil.getLogUrl(), " 删除" + specialName + "专题主题词分组信息");
            gm.delete(sql);
            FileUtil.writeToTxt(configUtil.getLogUrl(), " 删除" + specialName + "专题主题词");
            gm.delete(sql2);
            FileUtil.writeToTxt(configUtil.getLogUrl(), " 删除" + specialName + "专题主题词段落关系");
            gm.delete(sql3);
            FileUtil.writeToTxt(configUtil.getLogUrl(), " 删除" + specialName + "专题主题词之间关系");
            gm.delete(sql4);
            FileUtil.writeToTxt(configUtil.getLogUrl(), " 删除" + specialName + "专题主题词之间置信度");
            wm.updateNames();/*设置数据库字符集  临时生效*/
            logger.info("------开始更新" + specialName + "专题主题词表------");
            FileUtil.writeToTxt(configUtil.getLogUrl(), "------开始更新" + specialName + "专题主题词表------");
            for (Theme theme : list) {
                String fileName = theme.getFileName();
                if (null != fileName || fileName != "") {
                    /*录入主题词*/
                    total += recordingWords(url + "/dataFiles/" + fileName, theme.getThemeId(), specialId);
                }
            }
            long t2 = System.currentTimeMillis();
            logger.info("------" + specialName + "专题主题词表更新完成，耗时：" + (t2 - t1) / 1000 + "s，共：" + total + "个词------");
            FileUtil.writeToTxt(configUtil.getLogUrl(), " " + specialName + "专题主题词表更新完成，耗时：" + (t2 - t1) / 1000 + "s，共：" + total + "个词");
            return EdatResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("{\"status\":\"1\",\"msg\":\"主题词表更新失败\",\"data\":\"\"}");
            throw e;
        }
    }

    /**
     * @Author:renqiang
     * @Param:path文件路径,type词语类型
     * @Description:录入主题词，主题词排重，别名不排重
     * @Date:13:16 2017/8/15
     */
    public int recordingWords(String path, long type, long specialId) throws IOException {
        Workbook book = null;
        try {
            book = ExcelUtil.getExcelWorkbook(path);
            Sheet sheet = book.getSheetAt(0);
            int firstRowNum = sheet.getFirstRowNum();

            int lastRowNum = sheet.getLastRowNum();
            int num = 0;
            Theme theme = tm.selectByPrimaryKey(type);
            logger.info("开始更新<" + theme.getThemeName() + ">主题词");
            long t1 = System.currentTimeMillis();
            for (int i = firstRowNum + 1; i <= lastRowNum; i++) {
                Row row = sheet.getRow(i);
                if (row != null) {
                    int first = row.getFirstCellNum();
                    if (first < 0) {
                        continue;
                    }
                    Cell cell = row.getCell(first);
                    if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK) {
                        String name = ExcelUtil.getCellValue(row.getCell(0));
                        if (name.equals("")) {
                            continue;
                        }
                        List<Word> word3 = wm.selectOne(type, name, specialId);
                        if (word3.size() > 0) {
                            logger.warn("存在重复的主题词:" + theme.getThemeName() + ":" + name);
                        } else {
                            Word word = new Word();
                            word.setSpecialId(specialId);
                            try {
                                word.setWord(name);
                                word.setThemeType(type);
                                wm.insert(word);
                                num++;
                            } catch (Exception e) {
                                e.printStackTrace();
                                logger.warn("入库失败" + theme.getThemeName() + ":" + name);
                            }
                            List<Word> list1 = wm.selectMainWord(type, name, specialId);
                            if (list1.size() > 0) {
                                Word word1 = list1.get(0);
                                long wid = word1.getWordId();
                                word1.setParentId(wid);/*设置主词父id为词id*/
                                wm.updateByPrimaryKey(word1);
                                Cell cell1 = row.getCell(first + 1);
                                /*录入别名*/
                                if (cell1 != null && cell1.getCellType() != cell1.CELL_TYPE_BLANK && !ExcelUtil.getCellValue(row.getCell(1)).equals("")) {
                                    String alias = ExcelUtil.getCellValue(row.getCell(1));
                                    String[] array = alias.split(",|，");
                                    Set<String> strings = new HashSet<>();/*保存主题词和别名，进行排重*/
                                    strings.add(name);
                                    for (String tem : array) {
                                        tem=tem.trim();
                                        if(!tem.equals("")){
                                             /*过滤掉与当前主题词或别名重复的别名*/
                                            if(!strings.contains(tem)){
                                                Word word2 = new Word();
                                                word2.setSpecialId(specialId);
                                                word2.setParentId(wid);
                                                word2.setWord(tem);
                                                word2.setThemeType(type);
                                                wm.insert(word2);
                                                strings.add(tem);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            long t2 = System.currentTimeMillis();
            logger.info("更新<" + theme.getThemeName() + ">主题词完成，更新" + num + "个主题词，耗时" + (t2 - t1) / 1000 + "s");
            return num;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("词表更新失败");
            return 0;
        } finally {
            book.close();
        }
    }
}
